import global, { Skill, UserSkill } from "../../global";
import GameSkill from "../UI/gameSkill";
import OtherPlayers from "../UI/otherPlayers";
import PlayerMessage from "../UI/playerMessage";
import Big, { Spell } from "./big";
import Point_ts, { Mark, MarkType } from "./point";
import Small from "./small";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Player extends cc.Component {

    id:number = 0;             //后台id

    color:cc.Color = null;       //四个玩家四个颜色 红蓝棕紫

    small:Small = null;                 //小子节点
    arr_big:Set<Big> = new Set<Big>();   //大子节点们

    is_me:boolean = false;                      //是否是玩家自己
    playerMessage:PlayerMessage = null;         //玩家信息，不是自己时有效 

    action:number = 0;               //行动力
    power:number = 0;                //法力值
    num_unlockSkills = 0;            //解锁的技能数

    //实际的
    skill1:Skill = null;
    skill2:Skill = null;
    skill3:Skill = null;
    skill4:Skill = null;

    is_surrender:boolean = false;       //是否已经投降
    
    /**
     * 初始化
     */
    init(userSkill:UserSkill,id:number){
        this.id = id;
        //技能转成对象
        this.skill1 = global.JsontoSkill(userSkill.skill1);
        this.skill2 = global.JsontoSkill(userSkill.skill2);
        this.skill3 = global.JsontoSkill(userSkill.skill3);
        this.skill4 = global.JsontoSkill(userSkill.skill4);
        //如果是复盘
        if(global.is_replay){
            global.UI.Node_otherPlayers.getComponent(OtherPlayers).addPlayer(this);
            return;
        }
        //判断该玩家是不是自己
        if(id==global.id){
            this.is_me = true;
            global.mgr.me_player = this;
            global.UI.player_ts = this;
            global.UI.Node_left.color = this.color;
            global.UI.showAction();
            global.UI.showPower();
            global.UI.createSkillButton();
        }else{  //不是自己，新建
            global.UI.Node_otherPlayers.getComponent(OtherPlayers).addPlayer(this);
        }
    }

    /**
    * 不是自己回合，关闭自己的全部事件监听
    */
    offAll(){
        if(this.is_surrender){
            return;
        }
        this.small&&this.small.closeOn();
        for(let big_ts of Array.from(this.arr_big)){
            big_ts.offAll();
        }
    }

   /**
    * 回合交替，所有player都得执行这个,把之前的动画停了
    */
    turnReady(){
        if(!this.is_surrender){
            this.stopSmallRotate();
        }
        this.playerMessage&&this.playerMessage.hideFrame();
   }

    /**
    * 到我的回合
    */
    turnMe(){
        //UI变化，重新计时，小子旋转，右下角提示框
        if(global.is_replay||!this.is_me){    //不是玩家自己才会显示提示框
            this.playerMessage.showFrame();
            if(!global.is_replay){
                global.UI.Button_turnOver.active = false;
            }
            global.UI.turnOthers();
        }else{
            global.UI.Button_turnOver.active = true;
            global.UI.turnMe();
            //逻辑运算
            if(!this.small){    //第一回合，还没有小子
                global.persist.tip("请落小子");
                for(let node of global.mgr.Layer_map.children){
                    node.getComponent(Point_ts).onSmallDown();
                }
            }else{
                //开启小子和大子监听和提示
                this.small.openOn();
                this.arr_big.forEach(big_ts=>{
                    big_ts.openOn();
                });
            }
        }
        //获得行动力+技能点
        if(this.small){
            this.resetAction();
            this.changePower(1); 
        }
        //一天过去了
        //point
        global.mgr.map_point.forEach(point_ts=>{
            point_ts.arr_mark.forEach(mark=>{
                if(mark.id==this.id){
                    switch(mark.type){
                        case MarkType.AIM: 
                            global.effect.playJPHit(point_ts.node.position,mark.node);
                            this.scheduleOnce(()=>{
                                point_ts.JPHit(mark.id);
                                point_ts.arr_mark.delete(mark);
                            },.4);
                            break;
                        case MarkType.BLOODY:   this.oneDayZF(mark,point_ts);    break;
                        case MarkType.VARIABLE:
                            point_ts.gbwc(this.id);    //假随机,变地形
                            this.oneDayZF(mark,point_ts);
                            break;
                        case MarkType.QUAKE:
                            point_ts.arr_mark.delete(mark);
                            break;
                        case MarkType.MAZE:     this.oneDayZF(mark,point_ts);    break;
                        case MarkType.FOG:      this.oneDayZF(mark,point_ts);    break;
                        case MarkType.MERCY:    this.oneDayZF(mark,point_ts);    break;
                        case MarkType.SNOW:     this.oneDayZF(mark,point_ts);    break;
                        default:console.error("出现未知印记");
                    }
                }
            });
        });
        //小子
        this.small&&this.small.oneDay();
        //大子
        this.arr_big.forEach(big_ts=>{
            big_ts.oneDay();
        });
        //小子转
        this.small&&cc.tween(this.small.Sprite.node).by(.5,{angle:180}).repeatForever().start();
        //技能进入冷却,不是本人就不管了
        if(!global.is_replay&&this.id==global.id){
            global.UI.Node_content.children.forEach(node=>{
                node.getComponent(GameSkill).oneDay();
            });
        }
    }

    /**
     * 阵法过去一天
     */
    oneDayZF(mark:Mark,point_ts:Point_ts){
        mark.time--;
        if(mark.time==0){
            if(mark.zf_node){
                mark.zf_node.destroy();
            }
            point_ts.arr_mark.delete(mark);
        }
    }

    /**
     * 清理阵法
     */
    clearZF(){
        global.mgr.map_point.forEach(point_ts=>{
            point_ts.arr_mark.forEach(mark=>{
                if(mark.id==this.id){
                    switch(mark.type){
                        
                        case MarkType.BLOODY:   mark.time = 1;this.oneDayZF(mark,point_ts);    break;
                        case MarkType.VARIABLE:
                            point_ts.gbwc(this.id);    //假随机,变地形
                            mark.time = 1;
                            this.oneDayZF(mark,point_ts);
                            break;
                        case MarkType.MAZE:     mark.time = 1;this.oneDayZF(mark,point_ts);    break;
                        case MarkType.FOG:      mark.time = 1;this.oneDayZF(mark,point_ts);    break;
                        case MarkType.MERCY:    mark.time = 1;this.oneDayZF(mark,point_ts);    break;
                        case MarkType.SNOW:     mark.time = 1;this.oneDayZF(mark,point_ts);    break;
                        default:console.error("出现未知印记");
                    }
                }
            });
        });
    }

    /**
     * 停止小子旋转动画
     */
    stopSmallRotate(){
        if(this.small){
            this.small.getComponent(Small).Sprite.node.angle = 0;
            this.small.getComponent(Small).Sprite.node.stopAllActions();
        }
    }

    /**
     * 让小子显示视野
     */
    showSmallView(){
        if(this.is_surrender){
            return;
        }
        if(this.small){
            let point_ts = this.small.node.parent.getComponent(Point_ts);
            point_ts.is_view = true;
            point_ts.display();
        }
    }

    /**
     * 行动力变化
     */
    changeAction(n: number) {
        this.action+=n;
        if(this.is_me){
            global.UI.showAction();
        }
    }

    /**
     * 行动力
     */
    resetAction() {
        if(this.num_unlockSkills == 4){
            this.action = 6;  
        }else{
            this.action = 4;
        }
        if(this.is_me){
            global.UI.showAction();
        }
    }

    /**
     * 法力值变化
     */
    changePower(n: number) {
        this.power+=n;
        if(this.is_me){
            //如果法力值足够，技能直接全部解锁
            if(this.getNeedPowerCost() == this.power){
                this.unlockskillAll();
            }
            global.UI.showPower();
        }
    }

    /**
     * 获取解锁全部技能法力值
     */
    getNeedPowerCost(){
        let need = (this.skill1.is_unlock?0:this.skill1.cost) + (this.skill2.is_unlock?0:this.skill2.cost) + (this.skill3.is_unlock?0:this.skill3.cost) + (this.skill4.is_unlock?0:this.skill4.cost);
        return need;
    }

    /**
     * 技能全部解锁
     */
    unlockskillAll(){
        global.music_ts.playEffect("Audio_skillUnlock");
        global.UI.Label_power.node.active = false;
        global.UI.Label_power.node.active = false;
        global.UI.Node_content.children.forEach(gameskill=>{
            let gameskill_ts = gameskill.getComponent(GameSkill);
            if(gameskill_ts.skill.is_unlock){
                return
            }
            gameskill_ts.Sprite_filter.node.active = false;
            gameskill_ts.skill.is_unlock = true;
            gameskill_ts.skill.time--;
            global.websocket.send(JSON.stringify({method:"unlockSkill",id:global.id}));
        })
    }

    /**
     * 我的行动操作
     */
    operation(data:any){
        switch(data.operation){
            case "smallBorn"    :this.smallBorn(data.index);                break;
            case "bigBorn"      :this.bigBorn(data.start,data.end);         break;
            case "bigMove"      :this.bigMove(data.start,data.end);         break;
            case "bigAttack"    :this.bigAttack(data.start,data.end);       break;
            case "toGhost"      :this.toGhost(data.index);                  break;
            case "toBone"       :this.toBone(data.index);                   break;
            case "toBattery"    :this.toBattery(data.index);                break;
            case "toKobold"     :this.toKobold(data.index);                 break;
            case "ghostMove"    :this.ghostMove(data.start,data.end);       break;
            case "batteryAttack":this.batteryAttack(data.start,data.end);   break;
            case "koboldMagic"  :this.koboldMagic(data.start,data.end);     break;
            //以下为技能衍生行动
            case "batteryAim"   :this.batteryAim(data.start,data.end);      break;
            case "CGMove"       :this.CGMove(data.start,data.end);          break;
            default:global.persist.tip("没有该行动");
        }
    }

    /**
     * 转地灵
     */
    toKobold(index:number) {
        let big_ts = global.mgr.map_point.get(index).node.getChildByName("大子").getComponent(Big);
        big_ts.toKobold();
    }
    /**
     * 转炮台
     */
    toBattery(index:number) {
        let big_ts = global.mgr.map_point.get(index).node.getChildByName("大子").getComponent(Big);
        big_ts.toBattery();
    }
    /**
     * 转顽石 
     */
    toBone(index:number) {
        let big_ts = global.mgr.map_point.get(index).node.getChildByName("大子").getComponent(Big);
        big_ts.toBone();
    }
    /**
     * 转幽灵
     */
    toGhost(index:number) {
        let big_ts = global.mgr.map_point.get(index).node.getChildByName("大子").getComponent(Big);
        big_ts.toGhost();
    }

    /**
     * 事件监听归位
     */
    homing(){
        //point关闭
        global.mgr.map_point.forEach(point_ts=>{
            point_ts.offAll();
        });
        //其他玩家
        global.mgr.game_players.forEach(player=>{
            player.offAll();
        })
        //小子开启
        this.small&&this.small.openOn();
        //大子开启
        this.arr_big.forEach(big_ts=>{
            big_ts.closeOn();
            big_ts.openOn();
        })
    }

    /**
     * 落小子
     */
    smallDown(index: number) {
        let small = cc.instantiate(global.mgr.Prefab_small);
        let small_ts = small.getComponent(Small);
        small_ts.Sprite.node.color = this.color;
        this.small = small_ts;
        this.small.player = this;
        let point_ts = global.mgr.map_point.get(index);
        point_ts.node.addChild(small);
        small_ts.init();
        //播放音效
        global.music_ts.playEffect("Audio_small");
    }

    /**
     * 小子出大子
     */
    smallBorn(index: number) {
        let point_ts = global.mgr.map_point.get(index);
        point_ts.smallBorn(this);
    }

    /**
     * 大子出大子
     */
    bigBorn(start:number,end:number){
        let point_ts = global.mgr.map_point.get(end);
        point_ts.bigBorn(this,start);
    }

    /**
     * 大子移动
     */
    bigMove(start:number,end:number){
        let point_ts = global.mgr.map_point.get(end);
        point_ts.bigMove(this,start);
    }

    /**
     * 大子攻击
     */
    bigAttack(start:number,end:number){
        let point_ts = global.mgr.map_point.get(end);
        point_ts.bigAttack(this,start);
    }

    /**
     * 幽灵移动
     */
    ghostMove(start:number,end:number){
        let cost = 1;
        //减行动力
        if(this.action<cost){
            if(this.is_me){
                global.persist.tip(`需要${cost}点行动力`);
            }
            return;
        }
        this.changeAction(-cost);
        let point_ts = global.mgr.map_point.get(end);
        point_ts.ghostMove(this,start);
    }

    /**
     * 炮台攻击
     */
    batteryAttack(start:number,end:number){
        let cost = 1;
        //减行动力
        if(this.action<cost){
            if(this.is_me){
                global.persist.tip(`需要${cost}点行动力`);
            }
            return;
        }
        this.changeAction(-cost);
        let point_ts = global.mgr.map_point.get(end);
        point_ts.batteryAttack(start);
        
    }

    /**
     * 地灵推土
     */
    koboldMagic(start:number,end:number){
        let cost = 1;
        //减行动力
        if(this.action<cost){
            if(this.is_me){
                global.persist.tip(`需要${cost}点行动力`);
            }
            return;
        }
        this.changeAction(-cost);
        let point_ts = global.mgr.map_point.get(end);
        point_ts.koboldMagic(start,this);
    }

    /**
     * 炮瞄准
     */
    batteryAim(start:number,end:number){
        //减行动力
        let cost = 1;
        this.changeAction(-cost);
        //逻辑
        let start_pointTs = global.mgr.map_point.get(start);
        let end_pointTs = global.mgr.map_point.get(end);
        let mark = new Mark(this.id,MarkType.AIM);
        end_pointTs.arr_mark.add(mark);
        //在视野中才可以看到
        let flag = false;
        if(global.is_replay||start_pointTs.is_view){
            flag = true;
        }
        global.effect.playJPAim(start_pointTs.node.position,end_pointTs.node.position,mark,this.color,flag);
    }

    /**
     * 超鬼移动
     */
    CGMove(start:number,end:number){
        let cost = 1;
        //减行动力
        if(this.action<cost){
            if(this.is_me){
                global.persist.tip(`需要${cost}点行动力`);
            }
            return;
        }
        this.changeAction(-cost);
        let point_ts = global.mgr.map_point.get(end);
        point_ts.CGMove(this,start);
    }
}
